package com.example.huadu_server.user.service.impl;

import cn.dev33.satoken.secure.BCrypt;
import com.example.huadu_server.config.Response;
import com.example.huadu_server.oss.service.OssService;
import com.example.huadu_server.user.dto.UpdateInfoDTO;
import com.example.huadu_server.user.dto.UserInfoDTO;
import com.example.huadu_server.user.entity.User;
import com.example.huadu_server.user.mapper.UserMapper;
import com.example.huadu_server.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import java.util.Random;
import java.util.concurrent.TimeUnit;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private JavaMailSender mailSender;

    private static final String REDIS_KEY_PREFIX = "FORGET_PASS_CODE_";

    private static final String REDIS_KEY_PREFIX_EMAIL = "UPDATE_EMAIL_CODE_";

    @Value("${spring.mail.username}")  // 从配置文件中注入发件人邮箱
    private String senderEmail;

    @Override
    public Response<Boolean> isUserEnabled(int userId) {
        User user = userMapper.selectById(userId);
        if (user == null) {
            return new Response<>(404, "用户不存在", false);
        }
        boolean enabled = "normal".equalsIgnoreCase(user.getStatus());
        if (!enabled) {
            // 当用户被禁用时返回 423 状态码，表示账号被锁定
            return new Response<>(423, "您的账号已被禁用", false);
        }
        return new Response<>(200, "查询成功", true);
    }


    /*
            修改密码
     */
    @Override
    public Response<String> modifyPassword(int userId, String oldPassword, String newPassword, String confirmPassword) {
        // 先检查用户是否被禁用
        Response<Boolean> enabledResp = isUserEnabled(userId);
        if (enabledResp.getCode() != 200) {
            return new Response<>(enabledResp.getCode(), enabledResp.getMessage(), null);
        }

        // 查询用户信息
        User user = userMapper.selectById(userId);
        if (user == null) {
            return new Response<>(404, "用户不存在", null);
        }

        // 校验旧密码
        if (!BCrypt.checkpw(oldPassword, user.getPassword())) {
            return new Response<>(400, "原密码错误", null);
        }

        // 校验新密码和确认密码是否一致
        if (!newPassword.equals(confirmPassword)) {
            return new Response<>(400, "新密码与确认密码不一致", null);
        }

        // 校验新密码是否合法
        if (newPassword.length() < 6 || newPassword.length() > 20) {
            return new Response<>(400, "新密码长度应在6到20字符之间", null);
        }

        // 更新密码
        user.setPassword(BCrypt.hashpw(newPassword, BCrypt.gensalt()));
        int rows = userMapper.updateById(user);

        if (rows > 0) {
            return new Response<>(200, "密码修改成功", null);
        } else {
            return new Response<>(500, "密码修改失败，请稍后再试", null);
        }
    }

    /*
         重置密码
    */
    @Override
    public Response<String> resetPassword(String email, String code, String newPassword, String confirmPassword) {
        // 验证码校验
        String redisCode = redisTemplate.opsForValue().get(REDIS_KEY_PREFIX + email);
        if (redisCode == null || !redisCode.equals(code)) {
            return new Response<>(400, "验证码错误或已过期", null);
        }

        // 校验新密码和确认密码是否一致
        if (!newPassword.equals(confirmPassword)) {
            return new Response<>(400, "新密码与确认密码不一致", null);
        }

        // 校验新密码长度
        if (newPassword.length() < 6 || newPassword.length() > 20) {
            return new Response<>(400, "新密码长度应在6到20字符之间", null);
        }

        // 查找用户并更新密码
        User user = userMapper.selectByEmail(email);
        if (user == null) {
            return new Response<>(404, "该邮箱未注册", null);
        }

        user.setPassword(BCrypt.hashpw(newPassword, BCrypt.gensalt()));
        int rows = userMapper.updateById(user);

        if (rows > 0) {
            redisTemplate.delete(REDIS_KEY_PREFIX + email); // 删除验证码
            return new Response<>(200, "密码重置成功", null);
        } else {
            return new Response<>(500, "密码重置失败，请稍后再试", null);
        }
    }

    //查看个人信息
    @Override
    public Response<User> getUserInfoById(int userId) {
        // 检查用户是否被禁用
        Response<Boolean> enabledResp = isUserEnabled(userId);
        if (enabledResp.getCode() != 200) {
            return new Response<>(enabledResp.getCode(), enabledResp.getMessage(), null);
        }
        // 根据用户 ID 查询用户信息
        User user = userMapper.selectById(userId);
        if (user == null) {
            return new Response<>(404, "用户不存在", null);
        }

        // 返回用户信息
        return new Response<>(200, "查询成功", user);

    }

    /**
     * 修改用户信息
     */
    @Override
    public Response<String> updateUserInfo(int userId, UpdateInfoDTO updateInfoDTO) {
        // 查询用户信息
        User user = userMapper.selectById(userId);
        if (user == null) {
            return new Response<>(404, "用户不存在", null);
        }

        // 更新用户信息
        if (updateInfoDTO.getUsername() != null) {
            user.setUsername(updateInfoDTO.getUsername());
        }
        if (updateInfoDTO.getPhone() != null) {
            user.setPhone(updateInfoDTO.getPhone());
        }
        if (updateInfoDTO.getGender() != null) {
            user.setGender(updateInfoDTO.getGender());
        }
        if (updateInfoDTO.getCareer() != null) {
            user.setCareer(updateInfoDTO.getCareer());
        }
        if (updateInfoDTO.getLogo() != null) {
            user.setLogo(updateInfoDTO.getLogo());
        }

        // 提交更新
        int rows = userMapper.updateById(user);
        if (rows > 0) {
            return new Response<>(200, "用户信息修改成功", null);
        } else {
            return new Response<>(500, "用户信息修改失败，请稍后再试", null);
        }
    }

    /*
        发送修改邮箱验证码
   */
    @Override
    public Response<String> sendUpdateEmailCode(String email) {
        // 检查邮箱是否存在
        User user = userMapper.selectByEmail(email);
        if (user != null) {
            return new Response<>(404, "该邮箱已注册", null);
        }

        // 生成验证码
        String code = String.format("%06d", new Random().nextInt(1000000));

        // 存储到 Redis，有效期5分钟
        redisTemplate.opsForValue().set(REDIS_KEY_PREFIX_EMAIL + email, code, 5, TimeUnit.MINUTES);

        // 发送邮件
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(senderEmail); // 发件人地址
        message.setTo(email);
        message.setSubject("花都优居平台");
        message.setText("您的验证码是：" + code + "，用于重置邮箱，有效期为5分钟。");

        try {
            mailSender.send(message);
            return new Response<>(200, "验证码已发送，请查收", code);
        } catch (Exception e) {
            return new Response<>(500, "发送验证码失败，请稍后再试", null);
        }
    }


    /**
     * 修改用户邮箱
     */
    @Override
    public Response<String> updateUserEmail(int userId, UserInfoDTO userInfoDTO) {
        // 查询用户信息
        User user = userMapper.selectById(userId);
        if (user == null) {
            return new Response<>(404, "用户不存在", null);
        }

        // 验证码校验
        String redisCode = redisTemplate.opsForValue().get(REDIS_KEY_PREFIX_EMAIL + userInfoDTO.getEmail());
        if (redisCode == null || !redisCode.equals(userInfoDTO.getCode())) {
            return new Response<>(400, "验证码错误或已过期", null);
        }

        // 更新用户信息
        if (userInfoDTO.getEmail() != null) {
            user.setEmail(userInfoDTO.getEmail());
        }

        // 提交更新
        int rows = userMapper.updateById(user);
        if (rows > 0) {
            return new Response<>(200, "用户信息修改成功", null);
        } else {
            return new Response<>(500, "用户信息修改失败，请稍后再试", null);
        }
    }

    @Override
    public Response<String> sendForgetPasswordCode(String email) {
        // 检查邮箱是否存在
        User user = userMapper.selectByEmail(email);
        if (user == null) {
            return new Response<>(404, "该邮箱未注册", null);
        }

        // 生成验证码
        String code = String.format("%06d", new Random().nextInt(1000000));

        // 存储到 Redis，有效期5分钟
        redisTemplate.opsForValue().set(REDIS_KEY_PREFIX + email, code, 5, TimeUnit.MINUTES);

        // 发送邮件
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(senderEmail); // 发件人地址
        message.setTo(email);
        message.setSubject("花都优居平台");
        message.setText("您的验证码是：" + code + "，用于重置密码，有效期为5分钟。");

        try {
            mailSender.send(message);
            return new Response<>(200, "验证码已发送，请查收", code);
        } catch (Exception e) {
            return new Response<>(500, "发送验证码失败，请稍后再试", null);
        }
    }

    /**
     * 上传用户头像
     */
    @Autowired
    private OssService ossService;

    @Override
    public Response<String> uploadUserLogo(@RequestParam("file") MultipartFile file, int userId) {
        try {
            // 调用 OssService 上传文件
            String fileUrl = ossService.uploadFile(file, "UserLogo");

            // 替换 HTTPS 为 HTTP
            fileUrl = fileUrl.replace("https://", "http://");

            // 更新数据库中用户头像字段
            User user = userMapper.selectById(userId);
            if (user == null) {
                return new Response<>(404, "用户不存在", null);
            }
            user.setLogo(fileUrl);
            userMapper.updateById(user);

            return new Response<>(200, "头像上传成功", fileUrl);
        } catch (RuntimeException e) {
            return new Response<>(500, e.getMessage(), null);
        }
    }
}

